<template>
  <div class='component-upload-image'>
    <el-upload
      ref='imageUpload'
      :action='uploadImgUrl'
      :before-upload='handleBeforeUpload'
      :class='{hide: this.fileList.length >= this.limit}'
      :file-list='fileList'
      :headers='headers'
      :limit='limit'
      :on-error='handleUploadError'
      :on-exceed='handleExceed'
      :on-preview='handlePictureCardPreview'
      :on-remove='handleDelete'
      :on-success='handleUploadSuccess'
      :show-file-list='true'
      list-type='picture-card'
      multiple
    >
      <i class='el-icon-plus'></i>
    </el-upload>

    <el-dialog
      :visible.sync='dialogVisible'
      append-to-body
      title='预览'
      width='800'
    >
      <img
        :src='dialogImageUrl'
        style='display: block; max-width: 100%; margin: 0 auto'
      />
    </el-dialog>
  </div>
</template>

<script>
import setting from '@/setting'
import cookies from '@/libs/util.cookies'
import { Loading, Message } from 'element-ui'

export default {
  props: {
    value: [String, Object, Array],
    // 图片数量限制
    limit: {
      type: Number,
      default: 5,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ['png', 'jpg', 'jpeg'],
    },
  },
  data() {
    return {
      number: 0,
      uploadList: [],
      dialogImageUrl: '',
      dialogVisible: false,
      hideUpload: false,
      baseUrl: setting.appInfo.imgUrl,
      uploadImgUrl: setting.appInfo.uploadUrl, // 上传的图片服务器地址
      headers: {
        token: cookies.get('token'),
      },
      fileSize: setting.upload.maxFileSize * 1024 * 1024,
      fileList: [],
      loading: null,
    }
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          // 首先将值转为数组
          const list = Array.isArray(val) ? val : this.value.split(',')
          // 然后将数组转为对象数组
          this.fileList = list.map(item => {
            if (typeof item === 'string') {
              if (item.indexOf(this.baseUrl) === -1) {
                item = { name: this.baseUrl + item, url: this.baseUrl + item }
              } else {
                item = { name: item, url: item }
              }
            }
            return item
          })
        } else {
          this.fileList = []
          return []
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 上传前loading加载
    handleBeforeUpload(file) {
      let isImg = false
      if (this.fileType.length) {
        let fileExtension = ''
        if (file.name.lastIndexOf('.') > -1) {
          fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
        }
        isImg = this.fileType.some(type => {
          if (file.type.indexOf(type) > -1) return true
          if (fileExtension && fileExtension.indexOf(type) > -1) return true
          return false
        })
      } else {
        isImg = file.type.indexOf('image') > -1
      }
      if (!isImg) {
        Message.error(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
        return false
      }
      if (this.fileSize) {
        const isLt = file.size < this.fileSize
        if (!isLt) {
          Message.error(`上传头像图片大小不能超过 ${setting.upload.maxFileSize} MB!`)
          return false
        }
      }
      this.loading = Loading.service({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      this.number++
    },
    // 文件个数超出
    handleExceed() {
      Message.error(`上传文件数量不能超过 ${this.limit} 个!`)
    },
    // 上传成功回调
    handleUploadSuccess(res, file) {
      if (res.code === setting.axiosConfig.successCode) {
        this.uploadList.push({ name: res.data[setting.upload.resFileName], url: res.data[setting.upload.resFileName] })
        this.uploadedSuccessfully()
      } else {
        this.number--
        this.loading.close()
        Message.error(res.msg)
        this.$refs.imageUpload.handleRemove(file)
        this.uploadedSuccessfully()
      }
    },
    // 删除图片
    handleDelete(file) {
      const findex = this.fileList.map(f => f.name).indexOf(file.name)
      if (findex > -1) {
        this.fileList.splice(findex, 1)
        this.$emit('input', this.listToString(this.fileList))
      }
    },
    // 上传失败
    handleUploadError() {
      Message.error('上传图片失败，请重试')
      this.loading.close()
    },
    // 上传结束处理
    uploadedSuccessfully() {
      if (this.number > 0 && this.uploadList.length === this.number) {
        this.fileList = this.fileList.concat(this.uploadList)
        this.uploadList = []
        this.number = 0
        this.$emit('input', this.listToString(this.fileList))
        this.loading.close()
      }
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 对象转成指定字符串分隔
    listToString(list, separator) {
      let strs = ''
      separator = separator || ','
      for (let i in list) {
        if (list[i].url) {
          strs += list[i].url.replace(this.baseUrl, '') + separator
        }
      }
      return strs != '' ? strs.substr(0, strs.length - 1) : ''
    },
  },
}
</script>
<style lang='scss' scoped>
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
  display: none;
}

// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
  transition: all 0s;
}

::v-deep .el-list-enter, .el-list-leave-active {
  opacity: 0;
  transform: translateY(0);
}
</style>
